#include <iostream>
#include <memory>
// Product

class Product {
public:
    virtual ~Product() { }
    virtual void say() = 0;
};

class ConcreteProduct :public Product {
public:
    ConcreteProduct() {
        std::cout << "ConcreteProduct..." << std::endl;
    }
    void say() {
        std::cout << "ConcreteProduct Say..." << std::endl;
    }
    ~ConcreteProduct() {
      std::cout << "~ConcreteProduct" << std::endl;
    }
};

// Factory

class Factory {
public:
    virtual std::shared_ptr<ConcreteProduct> CreateProduct() = 0;
    virtual ~Factory() { }
    Factory() { }
};

class ConcreteFactory :public Factory {
public:
    ConcreteFactory() {
        std::cout << "ConcreteFactory..." << std::endl;
    }

    ~ConcreteFactory() {
      std::cout << "~ConcreteFactory" << std::endl;
    }

    // Product* CreateProduct() {
        // return new ConcreteProduct();
    // }
    std::shared_ptr<ConcreteProduct> CreateProduct() {
        return std::make_shared<ConcreteProduct>();
    }
};

// Test

int main() {
    auto factory = std::make_unique<ConcreteFactory>();
    std::shared_ptr<ConcreteProduct>  product = factory->CreateProduct();
    product->say();
    return 0;
}
